/**
 *
 * @Author: Marek Zakowicz <mazak (at) debian (dot) linux.org.pl>
 *
 * Copyright (c) 2005, 2006, 2007 Marek Zakowicz. All rights reserved.
 *
 * Licence: This code may be used, (re)distribute and/or modify under the terms one of the following two kinds of licence:
 *          1) as free software under GPL 3 (General Public Licence ver. 3as published by the Free Software Foundation)
 *          2) as software under the terms individual licence from Marek Zakowicz
 *
 *          This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 *          without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */

package jsp2php;

import java.util.*;
import java.io.*;

import antlr.*;

import static jsp2php.StatementType.*;

public class JavaFragmentTranslator {
   OutputStream          out;
   NameSpace             nameSpace              = new NameSpace();
   StatementStack        stStack                = new StatementStack();
   boolean               printWS                = true; // okresla, czy biale znaki maja byc przepuszczane na wyjscie.
   StringBuilder         wsCache                = new StringBuilder();
   boolean               controlStarted         = false;

   private final boolean debug=false;

   private void debug(String msg) {
      if(debug) {
         System.out.println();
         System.err.println(msg);
         System.err.flush();
      }
   }

   private void _print(String s) {
      if(s==null) {
         return;
      }
      try {
         int len = s.length();
         for(int i = 0; i < len; i++) {
            char c=s.charAt(i);
            if((c & 0xff00) != 0) {
               System.err.println("Char "+ (0+c) +" at pos. "+ i +" is multibyte!");
               continue;
            }
            out.write(c);
         }
      }
      catch(IOException e) {
         System.err.print("IOException: "+e);
      }
   }

   void printWS(String s) {
      if(printWS) {
         if(wsCache.length()>0) {
            _print(wsCache.toString());
            wsCache.setLength(0);
         }
         print(s);
      }
      else {
         wsCache.append(s);
      }
   }

   void print(String s) {
      if(wsCache.length()>0 && printWS) {
         _print(wsCache.toString());
         wsCache.setLength(0);
      }
      _print(s);
   }

   void blockBegin( String label, StatementType type ) {
      debug("BB1: " + label + " " + stStack.peek());
      nameSpace.pushContext();
      stStack.stBegin( label, type, true);
      debug("BB2: " + stStack.peek());
   }

   void blockEnd() {
      StatementStackItem i = stStack.peek();
      debug("BE: "+i);
      if(i!=null) {
         if(i.label!=null &&  i.type==BLOCK) {
            print(" while(false) /* : "+ i.label +" */;");
         }
      }
      stStack.stEnd();
      nameSpace.popContext();
      debug(nameSpace.toString());
   }

   void statementBegin(String label, StatementType type, boolean completed) {
      stStack.stBegin(label, type, completed);
   }

   void statementEnd() {
      stStack.stEnd();
   }

   void breakContinueStatement(String instr, String label) throws TranslatorException {
      stStack.stBegin(null, BREAK_CONTINUE, false); // Zdanie jest rozpoczynane glownie dlatego, ze wraz z nim mozna zamknac caly lancuch nieskompletowanych zdan.

      int level;
      if( label!=null || "break".equals(instr) ) {
         level = stStack.labelLevel( label );
         if( level < 1 ) {
            throw new TranslatorException("Error in "+ instr +" statement - unknown label: "+label);
         }
      }
      else {
         assert( label==null && "continue".equals(instr) );
         level = stStack.lastLoopLevel();
         if( level < 1 ) {
            throw new TranslatorException("Error in continue statement - none loop!");
         }
      }

      if( level == 1 ) {
         print(instr);
      }
      else {
         print(instr + " " + level);
      }
      if(label!=null) {
         print(" /* "+ label +" */");
      }
   }

}

